package fileby.model.impl.sources.impl;

import fileby.model.impl.sources.FileItem;
import com.google.inject.Inject;
import fileby.core.SourceType;
import fileby.core.IDisplayableFileSource;
import fileby.model.impl.sources.IFileSource;
import fileby.model.impl.sources.IFileSourceManager;
import fileby.model.impl.sources.IFileSourceProvider;
import java.util.ArrayList;

/**
 * Handles the sources, creates new sources and manages them.
 * @author Jacob
 */
public class FileSourceManager implements IFileSourceManager {

    private ArrayList<IFileSource> sources = new ArrayList();
    private IFileSource currentSource;
    private IFileSourceProvider fileSourceProvider;

    @Inject
    public FileSourceManager(IFileSourceProvider fileSourceProvider) {
        this.fileSourceProvider = fileSourceProvider;
    }

    public void switchCurrentSourceIndex(int index) {
        if (index >= 0 && index < sources.size()) {
            currentSource = sources.get(index);
        }
    }

    /**
     * Creates a new source, of the specified type.
     * @param sourceType
     * @return The new IDisplayableSource
     */
    public IDisplayableFileSource newSource(SourceType sourceType) {
        switch (sourceType) {
            case COMPUTER:
                IFileSource source = fileSourceProvider.create(SourceType.COMPUTER);
                sources.add(source);
                currentSource = source;
                return source;
            default:
                return null;
        }
    }

    /**
     * Creates a new foldersource and either replaces an old one or simply adds it.
     * @param path The path to the folder.
     * @param replace True if this source replaces the current source.
     * @return The new source.
     */
    public IDisplayableFileSource newSource(String path, boolean replace) throws NullPointerException {
        IFileSource source = fileSourceProvider.create(SourceType.FOLDER, path);
        if (replace) {
            int index = getSources().indexOf(currentSource);
            sources.remove(index);
            sources.add(index, source);
            currentSource = source;
        } else {
            sources.add(source);
        }
        return source;
    }

    public void switchCurrentSource(SourceType source, boolean replace) {
        IFileSource f;
        switch (source) {
            case COMPUTER:
                f =  fileSourceProvider.create(source);
                break;
            // Add more types here if needed
            default:
                f = fileSourceProvider.create(source);
        }

        if (replace) {
            int index = getSources().indexOf(currentSource);
            sources.remove(index);
            sources.add(index, f);
            currentSource = f;
        } else {
            sources.add(f);
        }
    }

    /**
     * Removes the source.
     * @param index index of the source to be removed
     * @return true if it was removed successfully, otherwise false.
     */
    public boolean removeSource(int index) {
        if (sources.size() > 1) {
            if (sources.get(index) == currentSource && index != 0) {
                currentSource = sources.get(index - 1);
            } else if (sources.get(index) == currentSource) {
                currentSource = sources.get(index + 1);
            }
            sources.remove(index);
            return true;
        }
        return false;
    }

    public int getCurrentSourceIndex() {
        return getSources().indexOf(currentSource);
    }

    /**
     * Sets the specified file either selected or unselected.
     * @param path Pathname to the file.
     * @param select True if the file is to be selected, otherwise unselected.
     */
    public void setSelected(String path, boolean select) {
        currentSource.setSelected(path, select);
    }

    /**
     * Sets all items in current source selected or unselected.
     * @param select True if everything is to be selected, otherwise deselect all.
     */
    public void setAllSelected(boolean select) {
        currentSource.setAllSelected(select);
    }

    /**
     * Sets a single file selected, deselects the rest.
     * @param path
     */
    public void setSingleSelected(String path) {
        currentSource.setSingleSelected(path);
    }

    public ArrayList<FileItem> getFileItems() {
        return currentSource.getFileItems();
    }

    /**
     * 
     * @return the current IDisplayableSource.
     */
    public IFileSource getCurrentSource() {
        return currentSource;
    }

    public IFileSource getSource(int index) {
        return sources.get(index);
    }

    public ArrayList<IDisplayableFileSource> getSources() {
        return new ArrayList(sources);
    }

    public IDisplayableFileSource searchInCurrentSource(String text) {
        IFileSource search = fileSourceProvider.create(SourceType.SEARCH, text);
        sources.add(search);
        return search;
    }

    public String getAbsolutePathOf(IDisplayableFileSource source) {
        return sources.get(getSources().indexOf(source)).getAbsolutePath();
    }
}
